﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// TCP网络服务
    /// </summary>
    public sealed class TService:IDisposable
    {
        private TcpListener acceptor;

        /// <summary>
        /// 所有连接的客户端通道
        /// </summary>
        private readonly Dictionary<long, TChannel> idChannels = new Dictionary<long, TChannel>();

        public TService(IPEndPoint iPEndPoint)
        {
            this.acceptor = new TcpListener(iPEndPoint);
            acceptor.Start();
        }

        /// <summary>
        /// 等待一个客户端的连接
        /// </summary>
        /// <returns></returns>
        public async Task<TChannel> AcceptChannel()
        {
            if (this.acceptor == null)
                throw new Exception("acceptor 是 null");

            TcpClient tcpClient = await this.acceptor.AcceptTcpClientAsync();
            TChannel channel = new TChannel(this, tcpClient);
            this.idChannels[channel.Id] = channel;
            return channel;
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="iPEndPoint"></param>
        /// <returns></returns>
        public TChannel ConnectChannel(IPEndPoint iPEndPoint)
        {
            TcpClient tcpClient = new TcpClient();
            TChannel channel = new TChannel(this, tcpClient, iPEndPoint);
            this.idChannels[channel.Id] = channel;
            return channel;
        }

        public void Dispose()
        {
            if (this.acceptor == null) return;
            foreach (var item in idChannels)
            {
                item.Value.Dispose();
            }
            this.acceptor.Stop();
            this.acceptor = null;
        }

        /// <summary>
        /// 获取连接通道
        /// </summary>
        /// <param name="channelId"></param>
        /// <returns></returns>
        public TChannel GetChannel(long channelId)
        {
            this.idChannels.TryGetValue(channelId,out TChannel channel);
            return channel;
        }

        /// <summary>
        /// 移除连接通道
        /// </summary>
        /// <param name="id"></param>
        public void Remove(long id)
        {

            if(!this.idChannels.TryGetValue(id,out TChannel channel))
            {
                return;
            }

            if (channel == null) return;

            this.idChannels.Remove(id);
            channel.Dispose();
        }
    }
}
